#!/usr/bin/env python
# -*- coding: utf-8 -*-

#######################################################################

ACTION_TYPE_NONE = 0
ACTION_TYPE_SEND = 1
ACTION_TYPE_RECV = 2
ACTION_TYPE_SENDnRECV = 3

ACTION_DATA_TYPE_REQUEST  = 10
ACTION_DATA_TYPE_RESPONSE = 11

def passthru(arg):
    return arg


class   BaseAction(object) :
    def __init__(self, job=None) :
        self.action_type = ACTION_TYPE_NONE
        self.job = job
        self.remote_address = None
        self.remote_service = None

        self.data = None        # request
        self.data_type = ACTION_DATA_TYPE_REQUEST
        self.data_respid = 0

        self.result = None      # response
        self.reason = None      # failure

        self.__callbacks = []
        # __init__()

    def execute(self) :
        '''execute action, and return status-tuple

        on success, return (True, data), data will go to done()
        on failure, retunr (False, reason), reason will go to fail()
        '''
        return True,None
        # execute()

    def done(self, data=None) :
        #self.result = data
        self.result = data
        while self.__callbacks :
            item = self.__callbacks.pop(0)
            callback, args, kwargs = item[0]    #isinstance(self.result, failure.Failure)]
            args = args or ()
            kwargs = kwargs or {}
            self.result = callback(self.result, *args, **kwargs)
        # done()
    def fail(self, reason=None) :
        self.reason = reason
        while self.__callbacks :
            item = self.__callbacks.pop(0)
            callback, args, kwargs = item[1]    #isinstance(self.result, failure.Failure)]
            args = args or ()
            kwargs = kwargs or {}
            self.reason = callback(self.reason, *args, **kwargs)
        # fail()

    def addCallBack(self, callback, *args, **kw) :
        return self.addCallbacks(callback, callbackArgs=args,
                                 callbackKeywords=kw)
        # addCallBack()
    def addErrorBack(self, errorback, *args, **kw) :
        return self.addCallbacks(passthru, errorback,
                                 errorbackArgs=args,
                                 errorbackKeywords=kw)
        # addErrorBack()
    def addCallbacks(self, callback, errorback=None,
                     callbackArgs=None, callbackKeywords=None,
                     errorbackArgs=None, errorbackKeywords=None) :
        cbs = ((callback, callbackArgs, callbackKeywords),
               (errorback or (passthru), errorbackArgs, errorbackKeywords))
        self.__callbacks.append(cbs)
        # addCallbacks()

    def isSendAction(self) :
        return self.action_type == ACTION_TYPE_SEND
        # isSendAction()
    def isRecvAction(self) :
        return self.action_type == ACTION_TYPE_RECV
        # isRecvAction()
    def isSendRecvAction(self) :
        return self.action_type == ACTION_TYPE_SENDnRECV
        # isSendRecvAction()
    # class BaseAction

#######################################################################


class   SendAction(BaseAction) :
    def __init__(self, job=None) :
        BaseAction.__init__(self, job)
        self.action_type = ACTION_TYPE_SEND
        # __init__()
    # class SendAction()

class   RecvAction(BaseAction) :
    def __init__(self, job=None) :
        BaseAction.__init__(self, job)
        self.action_type = ACTION_TYPE_RECV
        # __init__()
    # class SendAction()

class   SendRecvAction(BaseAction) :
    def __init__(self, job=None) :
        BaseAction.__init__(self, job)
        self.action_type = ACTION_TYPE_SENDnRECV
        # __init__()
    # class SendAction()

#######################################################################

__all__ = [ 'BaseAction', 'SendAction', 'RecvAction', 'SendRecvAction', 'ACTION_DATA_TYPE_RESPONSE' ]
